package com.quick.proxy.core.handler;

import com.quick.proxy.core.ProtocolConstants;
import com.quick.proxy.core.config.ProxyConfig;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Description: 子通道处理程序
 * Author: 吃素不吃肉
 * Date: 2023/7/4
 *
 * @author 吃素不吃肉
 */
@Component
@Lazy
public class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
    private static final EventExecutorGroup TRANS_GROUP = new DefaultEventExecutorGroup(16);
    private final ProxyConfig proxyConfig;
    private final HeartBeatHandler heartBeatHandler;
    private final ProtocolEncoder protocolEncoder;
    private final ProtocolDisposeHandler protocolDisposeHandler;
    private final ProtocolOutboundHandler protocolOutboundHandler;
    private final List<ProxyChannelInboundHandlerAdapter> proxyChannelInboundHandlerAdapters;

    public ChildChannelHandler(ProxyConfig proxyConfig, HeartBeatHandler heartBeatHandler, ProtocolEncoder protocolEncoder, ProtocolDisposeHandler protocolDisposeHandler, ProtocolOutboundHandler protocolOutboundHandler, List<ProxyChannelInboundHandlerAdapter> proxyChannelInboundHandlerAdapters) {
        this.proxyConfig = proxyConfig;
        this.heartBeatHandler = heartBeatHandler;
        this.protocolEncoder = protocolEncoder;
        this.protocolDisposeHandler = protocolDisposeHandler;
        this.protocolOutboundHandler = protocolOutboundHandler;
        this.proxyChannelInboundHandlerAdapters = proxyChannelInboundHandlerAdapters;
    }

    @Override
    protected void initChannel(SocketChannel arg0) {
        arg0.pipeline().addLast(new IdleStateHandler(proxyConfig.getReaderIdleTime(), proxyConfig.getWriterIdleTime(), proxyConfig.getAllIdleTime(), TimeUnit.SECONDS));
        //lengthAdjustment  = (stx+rsCtl+cmdType+length)+数据包长度(data+bcc) - lengthFieldOffset - lengthFieldLength - 长度域的值(data)
        arg0.pipeline().addLast(new LengthFieldBasedFrameDecoder(Math.max(proxyConfig.getMaxDataSize() * 1024, 65535), 4, ProtocolConstants.getLengthSize(), 1, 0));
        arg0.pipeline().addLast(new ProtocolDecoder());
        arg0.pipeline().addLast(this.heartBeatHandler);
        for (ProxyChannelInboundHandlerAdapter proxyChannelInboundHandlerAdapter : proxyChannelInboundHandlerAdapters) {
            arg0.pipeline().addLast(proxyChannelInboundHandlerAdapter);
        }
        arg0.pipeline().addLast(this.protocolOutboundHandler);
        arg0.pipeline().addLast(this.protocolEncoder);
        arg0.pipeline().addLast(TRANS_GROUP, this.protocolDisposeHandler);
    }

}
